perm filename WALDSK.SAI[SYS,HE] blob sn#055854 filedate 1973-07-30 generic text, type T, neo UTF8
00100	BEGIN "WALEYE" 
00200	
00300	COMMENT   This is a corner finding program using the Hueckel
00400		edge_operator. It will find lines, corners 
00500		with 2 sides and physical corners with 3 sides;
00600	
00700	
00800	REQUIRE "{ } { }" DELIMITERS;
00900	REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
01000	REQUIRE "HELIB[1,3]" LIBRARY;
01100	REQUIRE "EDGE.HDR[VIS,WAP]" SOURCE_FILE;
01200	REQUIRE "SAITRG[SYS,BGB]" SOURCE_FILE;
01300	
01400	DEFINE DINT="2."; COMMENT THIS IS USED AS RADIUS IN WHICH WE
01500			CONSIDER NEW VERTEX TO BE THE SAME AS ONE
01600			FOUND PREVIOUSLY;
01700	
01800	
01900	DEFINE SINDIR="12", COSDIR="13", SINTHETA="9", COSTHETA="10";
02000	
02100	
02200	SHORT REAL SCAL;
02300	SHORT INTEGER REQUEST,EXFLAG,DUMMY,MINI,MAXI,DE,INTS,LINS;
02400	SHORT INTEGER ARRAY STOR[1:25],HIST[-1:16];
02500	SHORT INTEGER EXT,PPN,FAIL,BRK,NCORNERS,CORNERNUMBER;
02600	BOOLEAN EXT_LINE;
02700	STRING PIC;
02800	INTEGER ARRAY ITEMVAR TVPIC;
02900	
03000	
03100	EXTERNAL PROCEDURE PICINI(INTEGER C,F,E,P,G;INTEGER ARRAY S);
03200	EXTERNAL PROCEDURE PICRD(INTEGER FAIL; INTEGER ARRAY S);
03300	EXTERNAL INTEGER PROCEDURE GIOWD(INTEGER ARRAY BUF);
03400	EXTERNAL PROCEDURE INTPNT;
03500	EXTERNAL INTEGER PROCEDURE GETPNT(INTEGER X,Y);
03600	EXTERNAL INTEGER TVWORD, LSIDE,RSIDE,FLINE,LLINE,BITS;
03700	
03800	comment to run without PREAMB the following declarations should be added here;
03900	comment	BOOLEAN DIS_EYE,DEB_EYE,TYP_EYE;
04000	comment REAL ARRAY DIR_EYE[0:10,1:8];
04100	comment INTEGER ARRAY LOOK_AT[1:8];
04200	
04300	DEFINE ⊃="COMMENT", DPYBUF="BUF", INTEGER_ARRAY="INTEGER ARRAY";
04400	DEFINE CRLF="'15&'12", ACRLF="&'15&'12";  DEFINE YES="INCHWL=""Y""";
04500	DEFINE PRINT(FOO)={OUTSTR("  FOO="&CVG(FOO)ACRLF);};
04600	DEFINE WAIT="IF DEB_EYE THEN BEGIN OUTSTR(""...TYPE Y TO CONTINUE...""ACRLF);
04700	             IF INCHWL=""Y"" THEN; END";
     

00100		SHORT INTEGER X, Y,DX,DY, NHIGH,NLINES,NVERTEX,NDRES;
00200		SHORT INTEGER X_WIDTH,Y_WIDTH;
00300		SHORT INTEGER EDGE_LIMIT, LT_LIMIT, LINE_LIMIT,VERT_LIMIT;
00400		SHORT REAL NDTH,NDC,NDS,NDCHI,NDRADIUS,NDGAP;
00500		SHORT REAL NDANG,NDACC, DELTA_X,DELTA_Y,DXY;
00600	BOOLEAN CAL_COMP; ⊃ IT TRUE THEN MAKE CALCOMP PLOTS OF SOME DISPLAYS;
00700	BOOLEAN CAL2_COMP; ⊃ IT TRUE THEN MAKE CALCOMP PLOTS OF SOME DISPLAYS.
00800		This is used for displaying SET_FOR_SCAN edge points;
00900	
01000	PROCEDURE INIT;
01100	BEGIN
01200	X←0;Y←0;DX←2;DY←2;
01300	
01400	
01500	⊃ Line finder variables;
01600	NDTH←0.23; ⊃ THIS SETS HALF THE THETA WINDOW FOR EDGE_POINTS FORMING A LINE;
01700	NDC←30.0; ⊃ THIS SETS HALF THE C WINDOW FOR EDGE_POINTS FORMING A LINE;
01800	NDRES←2; ⊃ THIS SETS SPACING IN THE RESIDUAL HISTOGRAM.
01900		   LARGER NUMBER MADE IT EASIER TO FIND A LINE;
02000	NDS←4.; ⊃ THIS SETS THE MINIMUM GAP LENGTH FOR WHICH 2 EDGE_POINTS
02100		  WILL BE JOINED TO FORM A SOLID LINE;
02200	NDCHI←1.0; ⊃ THIS SETS THE MAXIMUM ALLOWABLE CHI-VALUE
02300		      FOR A SET OF POINTS TO BE CONSIDERED A LINE;
02400	NDRADIUS←6; ⊃ RADIUS OF CIRCLE USED TO EXTEND END OF LINES;
02500	NDGAP←0.5; ⊃ MAXIMUM PERCENTAGE OF LENGTH FOR GAP BETWEEN EDGE POINTS;
02600	NDANG←0.15; ⊃ THIS DETERMINES THE ACCEPTABLE DIFFERENCE IN 
02700		     FOR TWO LINES TO BE MADE INTO ONE;
02800	NDACC←.75;  ⊃ THIS SETS THE ACCEPTABLE PERPENDICULAR DISTANCE BETWEEN
02900		   LINES AND VERTEX CENTER FOR A THREE LINE VERTEX;
03000	NHIGH←4; ⊃ IF THE NUMBER OF GOOD EDGE POINTS 
03100		   IS ≥ NHIGH + 1 THEN A LINE WILL BE FOUND EVENUTALLY;
03200	
03300	CAL_COMP←CAL2_COMP←0; ⊃ Used for Calcomp plots;
03400	
03500	⊃ Window variables;
03600	X_WIDTH←40;  ⊃ INITIAL WINDOW WIDTH;
03700	Y_WIDTH←30;  ⊃ INITIAL WINDOW HEIGHT;
03800	DELTA_X←X_WIDTH/2.-6;
03900	DELTA_Y←Y_WIDTH/2.-6;
04000	
04100	
04200	⊃ Array limits;
04300	EDGE_LIMIT←1200;
04400	LT_LIMIT←600;
04500	LINE_LIMIT← 15;
04600	VERT_LIMIT← 15;
04700	
04800	
04900	END;
05000	
05100	REQUIRE INIT INITIALIZATION;
     

00100	
00200	
00300	
00350	BOOLEAN WANT_ALL; ⊃ If true the find all corners. Otherwise find 
00375				one corner and stop;
00400	BOOLEAN DISP_HIST; ⊃ IF TRUE THEN DISPLAY HISTOGRAMS;
00500	BOOLEAN DISP_POINTS; ⊃ IF TRUE THEN DISPLAY THETA-C POINTS;
00550	BOOLEAN DISP_VERT; ⊃ If true then make extra vertes displays;
00600	SHORT INTEGER EDGE_COUNT,EDGE_INDEX,LEDGE_INDEX;
00700	DEFINE EDGE_BLSIZE = "4", EBS = "4",EDGE_X="0", EDGE_Y="1",
00800		EDGE_TH="2", EDGE_C="3";
00900	DEFINE PI1 = "3.1415927", SQ2 = "1.414214";
01000	DEFINE PIT2 = "6.283185", PIO2 = "1.570796", PI6=".523595";
01100	DEFINE  BUF_LIMIT="5000", BUF2_LIMIT="2", HUMP_LIMIT = "50";
01200	
01300	
01400	SHORT INTEGER X1,Y1,X2,Y2; ⊃ Window variables;
02100	
02200	REQUIRE "DPY2.HDR[VIS,WAP]" SOURCE_FILE;
     

00100	
00200	
00300	PROCEDURE INPUT;
00400	BEGIN "IN"
00500	⊃ THIS PROCEDURE READS IN A PICTURE FROM THE DISK;
00600	LABEL L1;
00700		NLINES←NVERTEX←0;
00800	L1:     OUTSTR(" INPUT FILE = "ACRLF);
00900		PIC ← INCHWL;
01000		PICINI(1,CVFIL(PIC,EXT,PPN),EXT,PPN,FAIL,STOR);
01100		IF FAIL∨¬STOR[1] THEN GO TO L1;
01200		STOR[2] ← 0;
01300		ARRBLT(STOR[3], STOR[2], 23);
01400		BEGIN
01500		INTEGER ARRAY TV[1:STOR[1]];
01600			IF TVPIC ≠ EVERY THEN GLOBAL DELETE(TVPIC);
01700			TVPIC ← GLOBAL NEW(TV);
01800		END;
01900		TVWORD ← GIOWD(GLOBAL DATUM(TVPIC));
02000		STOR[1] ← TVWORD +1;
02100		PICRD(FAIL,STOR);
02200		RELEASE(1);
02300		INTPNT; ⊃ THIS PROC. MUST BE CALLED SO THAT GETPNT CAN GET
02400			INTENSITY VALUES;
02500		EJINIT; ⊃ THIS INITIALIZES EDGED OPERATOR;
02600			DIS_EYE ← -1;
02700			DEB_EYE ← -1;
02800			EXFLAG ←1;
02900			LOOK_AT[6] ←0;
03000			LOOK_AT[7] ← 7;
03100	END "IN";
03200	
03300	
     

00100	
00200	
00300	PROCEDURE COR(INTEGER MODLINES,DIREC,SEARCH;
00400		REAL TOLER; REAL ARRAY CORNMOD);
00500	BEGIN "COR"
00600	
00700	SHORT INTEGER WSEARCH;
00800	
00900	
01000	
01100	SHORT INTEGER ARRAY WIND[0:X_WIDTH,0:Y_WIDTH];
01200	⊃ Array WIND is declared in an inner procedure so that
01300		X_WIDTH and Y_WIDTH can be selected at run time;
01400	
01500	
01600	SHORT REAL ARRAY EDGES[1:EDGE_LIMIT], 
01700		HUMPS[0:LINE_LIMIT,1:HUMP_LIMIT], VERTEX[1:VERT_LIMIT,1:10];
01800	SHORT REAL ARRAY INTER[1:2,1:5],LIN[1:3,1:5],FOLLOW[1:6];
01900	
02000	
02100	REQUIRE "EDGED.HDR[VIS,WAP]" SOURCE_FILE;
02200	REQUIRE "LINE.HDR[VIS,WAP]" SOURCE_FILE;
02300	
02400	
02500	
02600	
02700	SIMPLE PROCEDURE HISTO;
02800	  BEGIN "HISTO"
02900	  SHORT INTEGER I,X,Y;
03000	
03100	    ⊃ Compute the histogram;
03200	    FOR I←0 STEP 1 UNTIL 15 DO HIST[I]←0;
03300		FOR X←0 STEP 1 UNTIL LOOK_AT[4]-1 DO
03400	  	FOR Y←0 STEP 1 UNTIL LOOK_AT[5] DO
03500		BEGIN
03600			  I←WIND[X,Y];
03700			  HIST[I]←HIST[I]+1; 
03800		END;
03900	
04000	    ⊃ Find boundary levels;
04100		   I←0; WHILE (HIST[I]=0)∧(I<15) DO I←I+1; MINI←I;
04200		   I←15; WHILE (HIST[I]=0)∧(I>0)  DO I←I-1; MAXI←I;
04300		   LOOK_AT[6]←(15-MAXI) DIV 2;
04400		   LOOK_AT[7]←(15-MINI) DIV 2;
04500	  END "HISTO";
04600	
04700	
04800	
04900	
05000	PROCEDURE SLICE;
05100	⊃ Here we check the intensity distribution in the window;
05200	  BEGIN "SLICE"
05300	SHORT INTEGER ARRAY HIST1[0:15];
05400	SHORT INTEGER I,J,BAR,MAX;
05500	
05600		   HISTO;
05700		   IF LOOK_AT[6]=LOOK_AT[7] THEN
05800		   BEGIN
05900			  OUTSTR("SLICE-FAILED: 
06000				UNIFORM INTENSITY IN WINDOW (CLIPS="&
06100			   CVS(LOOK_AT[6])&")"ACRLF);
06200			  EXFLAG←10; RETURN; 
06300		    END;
06400	  END "SLICE";
06500	
06600	
06700	
06800	
06900	SIMPLE PROCEDURE SETWIND;
07000	
07100	⊃ This procedure is used for disk pictures only.
07200		Array WIND stores the intensity values;
07300	
07400	BEGIN
07600	SHORT INTEGER X,Y,XP,YP,FACTOR;
07700	DEFINE	XMIN ="LOOK_AT[2] - (LOOK_AT[4] DIV 2) -LSIDE",
07800		YMIN = "LOOK_AT[3] - (LOOK_AT[5] DIV 2) - FLINE";
07900			IF BITS≤4 THEN FACTOR←1 ELSE FACTOR←4;
08000		IF DEB_EYE∨WSEARCH≥1 THEN 
08100		BEGIN
08200	OUTSTR("WINDOW CENTER AT "&CVS(LOOK_AT[2])&"  "&CVS(LOOK_AT[3])ACRLF);
08300			INCHWL;
08400		END;
08500	
08600		FOR X←0 STEP 1 UNTIL LOOK_AT[4] DO
08700		FOR Y←0 STEP 1 UNTIL LOOK_AT[5] DO
08800		BEGIN
08900			XP ← X + XMIN;
09000			YP ← Y + YMIN;	
09100			WIND[X,Y] ← GETPNT(XP,YP) DIV FACTOR;	
09200		END;
09300	END;
09400	
09500	
09600	
     

00100	
00200	SIMPLE PROCEDURE DISPLAY;
00300	 ⊃ Display the array of intensity numbers in the window;
00400	
00500	BEGIN "DISPLAY"
00600	SHORT INTEGER X,Y, SCALE, XBOUND,YBOUND;
00700	SHORT REAL NUMB,DEL, DELX,DELY, MINSCAL;
00800	SHORT INTEGER X1,Y1,X2,Y2;
01000		X1←LOOK_AT[2]-(LOOK_AT[4] DIV 2);
01100		X2←LOOK_AT[2]+(LOOK_AT[4] DIV 2);
01200		Y1←LOOK_AT[3]-(LOOK_AT[5] DIV 2);
01300		Y2←LOOK_AT[3]+(LOOK_AT[5] DIV 2);
01400		INIT_DOMAIN(X1,Y2,X2,Y1); ⊃ Set scale for display;
01500		MINSCAL←SMALLER(LOOK_AT[4],LOOK_AT[5]);
01600		SCALE←(MINSCAL DIV 25)+1;
01700		XBOUND←TX(X1);
01800		YBOUND←TY(Y1);
01900		DELX←TX(X2)-XBOUND;
02000		DELY←TY(Y2)-YBOUND;
02100		NUMB←MINSCAL;
02200	⊃  OUTSTR(" IN DISPLAY-- NUMBER="&CVG(NUMB)ACRLF);
02300	⊃  OUTSTR(" XBOUND="&CVS(XBOUND)&"   YBOUND="&CVS(YBOUND)ACRLF);
02400		DEL←ABS(SMALLER(DELX,DELY))/(NUMB+1);
02500		XBOUND←XBOUND+15;
02600		YBOUND←YBOUND-25;
02700	
02800	    DPYTYP(-200,12,1); DPYSET(DPYBUF);
02900	    DPYBRT(5); DPYBIG(2);
03000		BOUNDARY(X1,Y2,X2,Y1);
03100		IF DEB_EYE THEN 
03200		BEGIN
03300		   AIVECT(-500,0); RVECT(0,320);
03400		   FOR X←0 STEP 1 UNTIL 16 DO 
03500		   BEGIN RVECT(-10,0); RIVECT(10,-20); END;
03600		   FOR X←0 STEP 1 UNTIL 3 DO 
03700		   BEGIN AIVECT(-530,100*X); DPYSST(CVS(5*X)); END;
03800	    AIVECT(-600,380); DPYSST("CLIPS");
03900	    AIVECT(-500,0); RVECT(HIST[0]/(SCALE),0);
04000	    FOR X←0 STEP 1 UNTIL 14 DO 
04100		BEGIN RVECT(0,20); RVECT((HIST[X+1]-HIST[X])/(SCALE),0); END;
04200	    RVECT(0,20); RVECT(-HIST[15]/(SCALE),0);
04300	    AIVECT(-600,40*(7-LOOK_AT[7])); RVECT(60,0);
04400	    AIVECT(-600,40*(8-LOOK_AT[6])); RVECT(60,0);
04500	    END;
04600	
04700	
04800	
04900	    AIVECT(-200,420); DPYSST("SCALE=1:"&CVS(SCALE)); DPYBIG(2);
05000	    FOR X←0 STEP SCALE UNTIL LOOK_AT[4]-1 DO
05100	    FOR Y←0 STEP SCALE UNTIL LOOK_AT[5]-1 DO 
05200		BEGIN
05300		   AIVECT(XBOUND+DEL*X,YBOUND-DEL*Y);
05400			DPYSST(CVS(WIND[X,Y])); 
05500		END;
05600		   DPYOUT(1); SETFORMAT(0,7);
05700	  END"DISPLAY";
     

00100	
00200	SIMPLE PROCEDURE GETPICTURE;
00300	BEGIN
00400		SETWIND;
00500		SLICE;
00600	END;
00700	
00800	
00900	
01000	
01100	REQUIRE "IMAGE.SAI[VIS,WAP]" SOURCE_FILE;
01200	
01300		WSEARCH←SEARCH;
01400	
01500	SRCHIMAG(MODLINES,DIREC,SEARCH,TOLER,CORNMOD);
01600	
01700	
01800	END "COR";
01900	
     

00100	
00200	PROCEDURE CORNFIT;
00300	BEGIN "CORNFIT"
00400	
00500	⊃ Now the driver program;
00600	
00700	
00800	
00900	SIMPLE PROCEDURE BOUNDARY(SHORT REAL X1,Y1,X2,Y2);
01000	BEGIN
01100		X1 ← TX(X1);
01200		Y1 ← TY(Y1);
01300		X2 ← TX(X2);
01400		Y2 ← TY(Y2);
01500		AIVECT(X1,Y1);
01600		AVECT(X1,Y2);
01700		AVECT(X2,Y2);
01800		AVECT(X2,Y1);
01900		AVECT(X1,Y1);
02000	END;
02100	
02200	
02300	SIMPLE PROCEDURE ARROW(REAL X,Y,DX,DY);
02400	BEGIN
02500	REAL FACTOR,X1,X2,Y1,Y2;
02600		FACTOR←1.5;
02700		DX←DX*FACTOR;
02800		DY←DY*FACTOR;
02900		X1 ← TX(X-DX);
03000		X2 ← TX(X+DX);
03100		Y2 ← TY(Y+DY);
03200		Y1 ← TY(Y-DY);
03300		AIVECT(X1,Y1);
03400		AVECT(X2,Y2);
03500		X1← TX(X+DX/2.-DY/2.);
03600		Y1← TY(Y+DY/2.+DX/2.);
03700		AIVECT(X1,Y1);
03800		AVECT(X2,Y2);
03900		Y1← TY(Y+DY/2.-DX/2.);
04000		X1← TX(X+DX/2.+DY/2.);
04100		AVECT(X1,Y1);
04200	END;
04300	
04400	
04500	
04600	SIMPLE PROCEDURE LINE_MOD(SHORT REAL CX,CY; REFERENCE SHORT REAL
04700		THETA,COSTH,SINTH);
04800	⊃ This procedure takes the direction cosines CX, CY and
04900		calculates the appropriate angle theta;
05000	
05100	BEGIN
05200		SHORT REAL PHI;
05300			IF ABS(CX) ≥.10@-8  THEN
05400			BEGIN 
05500				PHI ← ATAN(CY/CX);
05600				IF CX<0 THEN PHI←PHI+PI1;
05700			END  ELSE
05800			IF CY≥0 THEN PHI ← PIO2 ELSE PHI ← -PIO2;
05900			THETA ← PHI +PI1;		
06000			COSTH←COS(THETA);
06100			SINTH←SIN(THETA);
06200	IF DEB_EYE THEN  OUTSTR(CRLF&"PHI = " &CVG(PHI)
06300		           &"THETA = " &CVG(THETA)
06400	    		   &"  SINTH="&CVG(SINTH)
06500	    		   &"  COSTH="&CVG(COSTH)&CRLF);
06600	END;
06700	
06800	
06900	
07000	PROCEDURE DISP_MODEL(SHORT INTEGER N,DIREC; SHORT REAL XCM,YCM;
07100				SHORT REAL ARRAY CORNMOD);
07200	
07300	⊃ Here we calculate and display the model of a line or corner;
07400	
07500		BEGIN "MOD"
07600	
07700	
07800	REAL PROCEDURE SMALLER(REAL L1,L2);
07900	IF L1<L2 THEN RETURN(L1) ELSE RETURN(L2);
08000	
08100		SHORT REAL XC,YC, DX,DY,DPX,DPY,TXC,TYC,
08200			DX3,DY3, L,LO2;
08300		LABEL AFTER;
08400		⊃ DISPLAY MODEL OF LINE OR CORNER;
08500			⊃ OUTSTR(" DIREC="&CVS(DIREC)ACRLF);
08600			L←SMALLER(15.,SQRT(X_WIDTH*Y_WIDTH)/2.);
08700			LO2←L/2.;
08800			DPX←CORNMOD[1,COSTHETA]; DPY←CORNMOD[1,SINTHETA];
08900			DY←CORNMOD[1,COSDIR];  DX←CORNMOD[1,SINDIR];
09000			XC←XCM-LO2*DX; YC←YCM-LO2*DY;
09100			IF N=1 THEN 
09200			BEGIN
09300				AIVECT(TX(XC),TY(YC));
09400				AVECT(TX(XCM+LO2*DX),TY(YCM+LO2*DY));
09500				XC←XCM;  YC←YCM;
09600			END ELSE
09700			BEGIN
09800				TXC←TX(XCM);  TYC←TY(YCM);
09900				AIVECT(TX(XCM-L*DX),TY(YCM-L*DY));
10000				AVECT(TXC,TYC);
10100			END;
10200			ARROW(XC,YC,DPX,DPY);
10300			IF DIREC=0 THEN ARROW(XC,YC,-DPX,-DPY);
10400			IF N=1 THEN GO TO AFTER;
10500		⊃	IF ABS(DPY)>0.5 THEN ARROW(XC,YC-3,DX,DY)
10600			ELSE ARROW(XC-3,YC,DX,DY);
10700			IF N=2 THEN 
10800			BEGIN 
10900				AIVECT(TXC,TYC);
11000				DX←CORNMOD[2,SINDIR]; DY←CORNMOD[2,COSDIR];
11100				DPX←CORNMOD[2,COSTHETA];
11200				DPY←CORNMOD[2,SINTHETA];
11300				XC←XCM-LO2*DX; YC←YCM-LO2*DY;
11400				AVECT(TX(XCM-L*DX),TY(YCM-L*DY));
11500				ARROW(XC,YC,DPX,DPY);
11600				IF DIREC=0 THEN ARROW(XC,YC,-DPX,-DPY);
11700			⊃	IF ABS(DPY)>0.5 THEN 
11800				ARROW(XC,YC-3,DX,DY)
11900				ELSE ARROW(XC-3,YC,DX,DY);
12000				GO TO AFTER;
12100			END;
12200			DX←CORNMOD[2,SINDIR]; DY←CORNMOD[2,COSDIR];
12300			AIVECT(TX(XCM-L*DX),TY(YCM-L*DY));
12400			AVECT(TXC,TYC);
12500			DX3←CORNMOD[3,SINDIR]; DY3←CORNMOD[3,COSDIR];
12600			AVECT(TX(XCM-L*DX3),TY(YCM-L*DY3));
12700			DPX←CORNMOD[2,COSTHETA]; DPY←CORNMOD[2,SINTHETA];
12800	   		XC←XCM-LO2*DX; YC←YCM-LO2*DY;
12900	⊃		IF ABS(DPY)>0.5 THEN ARROW(XC,YC-3,DX,DY)
13000			ELSE ARROW(XC-3,YC,DX,DY);
13100			DPX←CORNMOD[3,COSTHETA]; DPY←CORNMOD[3,SINTHETA];
13200			XC←XCM-LO2*DX3; YC←YCM-LO2*DY3;
13300			ARROW(XC,YC,DPX,DPY);
13400			IF DIREC=0 THEN ARROW(XC,YC,-DPX,-DPY);
13500		⊃	IF ABS(DPY)>0.5 THEN ARROW(XC,YC-3,DX3,DY3)
13600			ELSE ARROW(XC-3,YC,DX3,DY3);
13700	AFTER:		DPYBIG(3);
13800			AIVECT(-300,420);
13900			DPYSST("MODEL OF CORNER");
14000			AIVECT(-500,380);
14100	DPYSST("ARROWS(PERPENDICULAR TO LINES) POINT FROM LIGHT TO DARK");
14200			DPYOUT(1);
14300		END "MOD";
14400	
14500	
     

00100	
00200	DEFINE XTIME(FOO)={XCEN+10.*SIN(PI6*(FOO))};
00300	DEFINE YTIME(FOO)={YCEN-10.*COS(PI6*(FOO))};
00400	SHORT INTEGER I,DIREC, SIGD, SEARCH,J,MODLINES,SIZE;
00500	SHORT REAL XIB,YIB,XIC,YIC,XID,YID,XIE,YIE,XIBB,YIBB,XCEN,YCEN;
00600	SHORT REAL TOLER,CX,CY,CX1,CY1,XX1,YY1,XX2,YY2,TIME1,TIME2,TIME3;
00700	
00800		SHORT REAL T1RAD,T2RAD,T3RAD;
00900		REAL TIME;
01000	
01100	STRING INSTRING,TYPE_CORN;
01200	SHORT REAL ARRAY CORNMOD[1:3,8:13];
01300	    LABEL LOOP,LOOP2,PAR,PARMS,NEWPIC,SETSIG,WIN;
01400		COMMENT LABELS MUST BE DECLARED BEFORE USE -- IN FACT, THEY HAVE 
01500		    TO BE DECLARED WITHIN THE INNER-MOST BLOCK IN WHICH THE 
01600		    STATEMENT BEING LABELED APPEARS. (SEE SAIL 3.4);
01700	
01800	
01900	
02000	INTEGER PROCEDURE LARGER(SHORT INTEGER L1,L2);
02100	IF L1>L2 THEN RETURN(L1) ELSE RETURN(L2);
02200	
02300	
02400	    ⊃ Main Program;
02500	   	TVPIC ← EVERY;
02600	NEWPIC:	INPUT; ⊃ THIS READS IN A PICTURE FROM THE DISK;
02700	    DIS_EYE←TRUE; DEB_EYE←FALSE;
02800	 	OUTSTR(" ARE YOU DEBUGGING AND WANT ALL POSSIBLE OUTPUT?  
02900			Y  OR  N?  "ACRLF);
03000	 	IF INCHWL="Y" THEN DEB_EYE←TRUE;
03100	
03200	   OUTSTR(" DO YOU WANT CALCOMP PLOTS?  Y OR N?"ACRLF);
03300	 	IF INCHWL≠"Y" THEN CAL_COMP←0 ELSE 
03325		BEGIN
03350			CAL_COMP←-1;
03375			OUTSTR(CRLF&" STARTING CORNER NUMBER FOLLOWED BY <CR> ");
03385			CORNERNUMBER←CVD(INCHWL);
03395		END;
03400	
03500	WIN:	OUTSTR(" THE STANDARD OR PRESENT WINDOW SIZE IS:
03600		WIDTH="&CVS(X_WIDTH)&"  HEIGHT="&CVS(Y_WIDTH)&
03700		"  DO YOU WANT TO CHANGE IT?   Y OR N?  "ACRLF);
03800		IF INCHWL="Y" THEN 
03900		BEGIN
04000			OUTSTR(" WIDTH AND HEIGHT 
04100			EACH FOLLOWED BY A CARRIAGE-RETURN "ACRLF);
04200			X_WIDTH←CVD(INCHWL);
04300			Y_WIDTH←CVD(INCHWL);
04400			DELTA_X←X_WIDTH/2.-6;
04500			DELTA_Y←Y_WIDTH/2.-6;
04600			IF SEARCH≥1 THEN
04700			BEGIN
04800				DELTA_X←DELTA_X+4;
04900				DELTA_Y←DELTA_Y+4;
05000			END;
05100			SIZE←X_WIDTH*Y_WIDTH;
05200			EDGE_LIMIT←LARGER(1200,SIZE);
05300			LT_LIMIT←LARGER(600,SIZE/4);
05400			LINE_LIMIT←LARGER(15,SIZE/80);
05500			VERT_LIMIT←LINE_LIMIT;
05600			GO TO WIN;
05700		END;
05800	
05900	
06000	LOOP:	OUTSTR(" ARE YOU LOOKING FOR A LINE,SIMPLE CORNER(2 SIDES),
06100		OR PHYSICAL CORNER(3 SIDES)?  [TYPE L,C, OR P] "ACRLF);
06200	
06300		MODLINES←0;
06400		TYPE_CORN←INCHWL;
06500		IF TYPE_CORN="L" THEN
06600		BEGIN
06700			MODLINES←1;
06800			OUTSTR(" ONE LINE WITH 3 NUMBERS, THE FIRST TWO 
06900	DESIGNATE THE CENTER OF THE LINE IN SCREEN COORDINATES,
07000	THE THIRD IS THE VALUE OF THE HOUR HAND WHEN IT IS PARALLEL TO THE
07100	LINE WHILE THE FORTH IS ANY HOUR-HAND SETTING ON THE SIDE OF THE 
07200	OBJECT."ACRLF);
07300		END;
07400		IF TYPE_CORN="C" THEN
07500		BEGIN
07600			MODLINES←2;
07700			OUTSTR(" ONE LINE WITH 4 NUMBERS THE FIRST TWO
07800	DESIGNATES THE VERTEX IN SCREEN COORDINATES WHILE THE OTHERS GIVE 
07900	THE ANGLES OF THE LINES IN HOUR-HAND VALUES IN A CLOCKWISE MANNER 
08000			ABOUT THE VERTEX."ACRLF);
08100		END;
08200		IF TYPE_CORN="P" THEN
08300		BEGIN
08400			MODLINES←3;
08500			OUTSTR(" ONE LINE WITH 5 NUMBERS THE FIRST TWO
08600	DESIGNATES THE VERTEX IN SCREEN COORDINATES WHILE THE OTHERS GIVE 
08700	THE ANGLES OF THE LINES IN HOUR-HAND VALUES IN A CLOCKWISE MANNER 
08800			ABOUT THE VERTEX."ACRLF);
08900		END;
09000		IF MODLINES=0 THEN GO TO LOOP;
09100	
09200	
09300	             INSTRING ← INCHWL;
09400		      XIB ← REALSCAN(INSTRING,DUMMY);
09500		      YIB ← REALSCAN(INSTRING,DUMMY);
09600		      TIME1 ← REALSCAN(INSTRING,DUMMY);
09700		      TIME2 ← REALSCAN(INSTRING,DUMMY);
09800		      TIME3 ← REALSCAN(INSTRING,DUMMY);
09900	
10000	    
10100	PARMS: NLINES←NVERTEX←NCORNERS←0;
10200	
10300	OUTSTR(" ONE LINE WITH 3 WAL PARAMETERS.
10400		FIRST IS INTENSITY:
10500			-1 FOR DARKER OUTSIDE
10600			 0 FOR UNKNOWN
10700			 1 FOR LIGHTER OUTSIDE
10800		SECOND IS SEARCH:
10900			-1 FOR USE WINDOW ONLY
11000			N≥1 FOR SEARCH IN AN AREA OF DIMENSION
11100			     N(INTEGER) ABOUT INITIAL WINDOW
11200		THIRD IS TOLERANCE OF ANGLE MATCH:
11300			USUALLY 0.1 BUT DOWN TO 0.02 WITH CARE.
11400			IF TOLERANCE IS >1 THEN ANY CORNER
11500			WILL BE ACCEPTED."ACRLF);
11600	
11700	
11800		INSTRING←INCHWL;
11900		DIREC←REALSCAN(INSTRING,DUMMY);
12000		  SEARCH←REALSCAN(INSTRING,DUMMY);
12100		TOLER←REALSCAN(INSTRING,DUMMY);
12200	
12300		IF TOLER>1 THEN DIREC←0;
12400	SETSIG: IF DIREC=0 THEN SIGD←1 ELSE SIGD←DIREC;
12500		XCEN←XIB; YCEN←YIB;
12600	
12700		
12800		IF TYPE_CORN="L" THEN
12900		BEGIN
13000			XIBB←XTIME(TIME1+6.);
13100			YIBB←YTIME(TIME1+6.);
13200			XIC←XTIME(TIME1);
13300			YIC←YTIME(TIME1);
13400			YID←YTIME(TIME2);
13500			XID←XTIME(TIME2);
13600			IF XIC*XIC+YIC*YIC≥XIBB*XIBB+YIBB*YIBB THEN
13700			BEGIN
13800				X2←XIC;  X1←XIBB;
13900				Y2←YIC;  Y1←YIBB;
14000			END ELSE
14100			BEGIN
14200				X1←XIC;  X2←XIBB;
14300				Y1←YIC;  Y2←YIBB;
14400			END;
14500			CX1←Y1-Y2; CY1←X2-X1;
14600			XX1←XCEN+CX1; YY1←YCEN+CY1;
14700			XX2←XCEN-CX1; YY2←YCEN-CY1;
14800			IF(XX1-XID)↑2+(YY1-YID)↑2≥(XX2-XID)↑2+(YY2-YID)↑2 THEN
14900			BEGIN CX←CX1; CY←CY1; END
15000			ELSE BEGIN CX←-CX1; CY←-CY1; END;
15100			CX←CX*SIGD; CY←CY*SIGD;
15200	     LINE_MOD(CX,CY,CORNMOD[1,8],CORNMOD[1,COSTHETA],CORNMOD[1,SINTHETA]);
15300			CORNMOD[1,11]←-SIGD;
15400			CORNMOD[1,SINDIR]←CORNMOD[1,11]*CORNMOD[1,SINTHETA];
15500			CORNMOD[1,COSDIR]←-CORNMOD[1,11]*CORNMOD[1,COSTHETA];
15600			GO TO LOOP2;
15700		END;
15800		IF TYPE_CORN="C" THEN 
15900		BEGIN
16000			XIC←XTIME(TIME1);
16100			YIC←YTIME(TIME1);
16200			YID←YTIME(TIME2);
16300			XID←XTIME(TIME2);
16400			CX←(YIC-YIB)*SIGD;
16500			CY←(XIB-XIC)*SIGD;
16600	     LINE_MOD(CX,CY,CORNMOD[1,8],CORNMOD[1,COSTHETA],CORNMOD[1,SINTHETA]);
16700			CX←(YIB-YID)*SIGD;
16800			CY←(XID-XIB)*SIGD;
16900	     LINE_MOD(CX,CY,CORNMOD[2,8],CORNMOD[2,COSTHETA],CORNMOD[2,SINTHETA]);
17000			CORNMOD[1,11]←-SIGD; CORNMOD[2,11]←SIGD;
17100			FOR J←1 STEP 1 UNTIL MODLINES DO
17200			BEGIN
17300			CORNMOD[J,SINDIR]←CORNMOD[J,11]*CORNMOD[J,SINTHETA];
17400			CORNMOD[J,COSDIR]←-CORNMOD[J,11]*CORNMOD[J,COSTHETA];
17500			END;
17600			GO TO LOOP2;
17700		END;
17800		IF TYPE_CORN="P" THEN 
17900		BEGIN
18000			XIC←XTIME(TIME1);
18100			YIC←YTIME(TIME1);
18200			YID←YTIME(TIME2);
18300			XID←XTIME(TIME2);
18400			XIE←XTIME(TIME3);
18500			YIE←YTIME(TIME3);
18600			CX←(YIC-YIB)*SIGD;
18700			CY←(XIB-XIC)*SIGD;
18800	     LINE_MOD(CX,CY,CORNMOD[1,8],CORNMOD[1,COSTHETA],CORNMOD[1,SINTHETA]);
18900			CX←(YIB-YID)*SIGD;
19000			CY←(XID-XIB)*SIGD;
19100	     LINE_MOD(CX,CY,CORNMOD[2,8],CORNMOD[2,COSTHETA],CORNMOD[2,SINTHETA]);
19200			CX←(YIB-YIE)*SIGD;
19300			CY←(XIE-XIB)*SIGD;
19400	     LINE_MOD(CX,CY,CORNMOD[3,8],CORNMOD[3,COSTHETA],CORNMOD[3,SINTHETA]);
19500			CORNMOD[1,11]←-SIGD; CORNMOD[2,11]←CORNMOD[3,11]←SIGD;
19600			FOR J←1 STEP 1 UNTIL MODLINES DO
19700			BEGIN
19800			CORNMOD[J,SINDIR]←CORNMOD[J,11]*CORNMOD[J,SINTHETA];
19900			CORNMOD[J,COSDIR]←-CORNMOD[J,11]*CORNMOD[J,COSTHETA];
20000			END;
20100		END;
20200	
20300	
20400	LOOP2:  IF DEB_EYE THEN INCHWL;
20500	
20600		X1←XCEN-X_WIDTH/2;
20700		X2←XCEN+X_WIDTH/2;
20800		Y2←YCEN+Y_WIDTH/2;
20900		Y1←YCEN-Y_WIDTH/2;
21000			DPYSET(BUF);
21100			INIT_DOMAIN(X1,Y2,X2,Y1);
21200			BOUNDARY(X1,Y2,X2,Y1);
21300			DISP_MODEL(MODLINES,DIREC,XCEN,YCEN,CORNMOD);
21400			IF CAL_COMP THEN CALCOMP("MODEL",BUF);
21500			INCHWL; INCHWL;
21600		OUTSTR(CRLF&"CENTER OF THE WINDOW "&
21700			CVG(XCEN)&"  "& CVG(YCEN) ACRLF);
21800	  		OUTSTR(" ARE YOU SATISFIED WITH THE MODEL?
21900			Y OR N? "ACRLF);
22000			DPYCLR;
22100			IF INCHWL="N" THEN GO TO LOOP;
22110		OUTSTR( " DO YOU WANT ALL CORNERS THAT MATCH?   Y OR N?"ACRLF);
22120			IF INCHWL="Y" THEN WANT_ALL←-1 ELSE WANT_ALL←0;
22200	⊃	IF ¬DEB_EYE THEN 
22300		BEGIN
22400			OUTSTR(" DO YOU WANT DISPLAYS?  Y OR N? "ACRLF);
22500	⊃		IF INCHWL="N"  THEN DIS_EYE←0 ELSE DIS_EYE←-1;
22600	⊃	END;
22700	⊃	TIME←CALL(0,"RUNTIM")/1000.;
22800	⊃	PRINT(TIME);
22900	
22950	    DIR_EYE[0,1]←0;
23000	    LOOK_AT[1] ← 1;
23100	    LOOK_AT[2] ← XCEN;
23200	    LOOK_AT[3] ← YCEN;
23300	    LOOK_AT[4] ← X_WIDTH;
23400	    LOOK_AT[5] ← Y_WIDTH;
23500	    CAL2_COMP←0;
23600	     	COR(MODLINES, DIREC, SEARCH, TOLER, CORNMOD);
23700		COMMENT   THIS IS THE CALL ON THE CORNER-FINDER "WALEYE". NOTICE
23800		    THAT THE FOUR PARAMETERS AND CORNMOD[...] ARE
23900		    PASSED AS ARGUMENTS.;
24000	
24100	
24200	⊃	TIME←CALL(0,"RUNTIM")/1000.;
24300	⊃	PRINT(TIME);
24400		IF EXFLAG≠0∨¬DIS_EYE THEN GO TO PAR;
24500		INCHWL; INCHWL;
24600		DISP_MODEL(MODLINES,DIREC,XCEN,YCEN,CORNMOD);
24700		INCHWL; INCHWL;
24800	
24900	
25000	
25100	PAR: 
25200	OUTSTR("DO YOU WANT TO CHANGE THE THREE WAL PARAMETERS? --- Y OR N"ACRLF);
25300		COMMENT   NOTICE THAT THE INPUT STRING IS ONLY COMPARED
25400		    WITH "Y".  IF IT IS A "Y" (OR STARTS WITH A "Y" --- CHECK
25500		    THE SAIL MANUAL FOR THE DETAILS OF STRING COMPARISONS ---
25600		    BASICALLY THE "=" COMPARISON ONLY COMPARES THE FIRST 
25700		    CHARACTERS.  THERE IS A BUILT-IN FUNCTION EQUAL(...)
25800		    WHICH COMPARES THE COMPLETE STRINGS.),  THE JUMP TO LOOP
25900		    WILL BE TAKEN.  IF THE INPUT STRING IS ANYTHING ELSE
26000		    (EVEN JUST A CARRIAGE-RETURN) THE JUMP WILL NOT BE TAKEN.
26100	
26200		    WARNING:   SOMETIMES THE OUTPUT MESSAGES (LIKE THE ONE
26300		    PRODUCED BY THE STATEMENT ABOVE) ARE INTERSPERSED WITH 
26400		    THE HAND/EYE TRACING INFORMATION.  IF EVERYTHING COMES
26500		    TO A HALT, LOOK THROUGH THE LAST FEW LINES OF THE TRACE
26600		    OUTPUT TO SEE IF ONE OF THE PROGRAM-PRODUCED QUESTIONS
26700		    OR REMARKS IS EMBEDDED THERE.;
26800	
26900	    IF INCHWL="Y" THEN GO TO PARMS;
27000	    OUTSTR("DO YOU WANT TO CHANGE THE MODEL? --- Y OR N"ACRLF);
27100	    IF INCHWL="Y" THEN GO TO LOOP;
27200	OUTSTR(" DO YOU WANT A NEW INPUT FILE? --- Y OR N "ACRLF);
27300		IF INCHWL≠"N" THEN GO TO NEWPIC;
27400	
27500	END "CORNFIT";
27600	
27700	CORNFIT;
27800	
27900	
28000	END "WALEYE";